Fix listing of untracked files to not include tracked but modified ones
authorFelix Crux <felixc@felixcrux.com>
Sun, 10 Jan 2016 19:47:02 +0000 (14:47 -0500)
committerFelix Crux <felixc@felixcrux.com>
Tue, 12 Jan 2016 00:40:03 +0000 (19:40 -0500)
The logic in `sources/path.rs` that finds files that are untracked by the
version control system was incorrectly including files that *are* tracked,
but had been modified without the modification being committed to Git.

This manifested itself as strange duplications of files (e.g. in `cargo
package --list`), since they were listed once as tracked files, and once
more as allegedly "untracked" ones. It also caused failures when trying to
package the crate when files had been deleted, but the deletion was not
yet committed to Git.

Fixes #2199

src/cargo/sources/path.rs
tests/test_cargo_package.rs

index 172fbe91dc2da18da48b6a60b4e37aad878dc95d..91162a5fe6a1deeaf9ecdf0e53687c486ab244a2 100644 (file)
@@ -161,8 +161,11 @@ impl<'cfg> PathSource<'cfg> {
             opts.pathspec(suffix);
         }
         let statuses = try!(repo.statuses(Some(&mut opts)));
-        let untracked = statuses.iter().map(|entry| {
-            (join(&root, entry.path_bytes()), None)
+        let untracked = statuses.iter().filter_map(|entry| {
+            match entry.status() {
+                git2::STATUS_WT_NEW => Some((join(&root, entry.path_bytes()), None)),
+                _ => None
+            }
         });
 
         'outer: for (file_path, is_dir) in index_files.chain(untracked) {
index 1a26ba359b991e0c67ca77fe77361d4436a21d9d..290e46354bb63034b2b88f381ea0ee3c1e473520 100644 (file)
@@ -371,6 +371,32 @@ test!(package_git_submodule {
     assert!(from_utf8(&result.stdout).unwrap().contains(&format!("{} bar/Makefile", ARCHIVING)));
 });
 
+test!(no_duplicates_from_modified_tracked_files {
+    let root = paths::root().join("all");
+    let p = git::repo(&root)
+        .file("Cargo.toml", r#"
+            [project]
+            name = "foo"
+            version = "0.0.1"
+            authors = []
+        "#)
+        .file("src/main.rs", r#"
+            fn main() {}
+        "#);
+    p.build();
+    File::create(p.root().join("src/main.rs")).unwrap().write_all(r#"
+            fn main() { println!("A change!"); }
+        "#.as_bytes()).unwrap();
+    let mut cargo = ::cargo_process();
+    cargo.cwd(p.root());
+    assert_that(cargo.clone().arg("build"), execs().with_status(0));
+    assert_that(cargo.arg("package").arg("--list"),
+                execs().with_status(0).with_stdout(&format!("\
+Cargo.toml
+src/main.rs
+")));
+});
+
 test!(ignore_nested {
     let cargo_toml = r#"
             [project]